#include <unistd.h>
#include "z_logger.h"
#include "service.h"
#include "aliot.h"
#include "aiot_ntp_api.h"

static void _ntp_recv_handler(void *handle, const aiot_ntp_recv_t *packet, void *userdata) {
    switch (packet->type) {
        case AIOT_NTPRECV_LOCAL_TIME:
            log_info("local time: %llu, %02d/%02d/%02d-%02d:%02d:%02d:%d",
                     packet->data.local_time.timestamp,
                     packet->data.local_time.year,
                     packet->data.local_time.mon,
                     packet->data.local_time.day,
                     packet->data.local_time.hour,
                     packet->data.local_time.min,
                     packet->data.local_time.sec,
                     packet->data.local_time.msec
            );
            char time[MAX_INPUT];
            sprintf(time, "date -s \"%02d-%02d-%02d %02d:%02d:%02d\"",
                    packet->data.local_time.year,
                    packet->data.local_time.mon,
                    packet->data.local_time.day,
                    packet->data.local_time.hour,
                    packet->data.local_time.min,
                    packet->data.local_time.sec);
            system(time) && system("hwclock -w");
            break;
        default:
            break;
    }
}

static void _ntp_event_handler(void *handle, const aiot_ntp_event_t *event, void *userdata) {
    switch (event->type) {
        case AIOT_NTPEVT_INVALID_RESPONSE:
            log_error("invalid_response");
            break;
        case AIOT_NTPEVT_INVALID_TIME_FORMAT:
            log_error("invalid time format");
            break;
        default:
            break;
    }
}

static void *_ntp_service_init(aliot_service_args_t *args) {
    void *ntp_handle = aiot_ntp_init();

    aiot_ntp_setopt(ntp_handle, AIOT_NTPOPT_MQTT_HANDLE, args->mqtt_handle);

    aiot_ntp_setopt(ntp_handle, AIOT_NTPOPT_RECV_HANDLER, _ntp_recv_handler);
    aiot_ntp_setopt(ntp_handle, AIOT_NTPOPT_EVENT_HANDLER, _ntp_event_handler);

    int8_t time_zone = 8;
    aiot_ntp_setopt(ntp_handle, AIOT_NTPOPT_TIME_ZONE, &time_zone);

    return ntp_handle;
}

static void _ntp_service_fini(void **handle) {
    aliot_error_check("aiot_ntp_deinit", aiot_ntp_deinit(handle));
}

static void *_ntp_service_start(void *handle) {
    aliot_error_check("aiot_ntp_send_request", aiot_ntp_send_request(handle));

    return NULL;
}

static aliot_service_t _ntp_service = {
        .name = "ntp",
        .init = _ntp_service_init,
        .fini = _ntp_service_fini,
        .start = _ntp_service_start,
        .stop = NULL
};

aliot_service_t *ntp_service_get() {
    return &_ntp_service;
}